home *** CD-ROM | disk | FTP | other *** search
/ Assassins - Ultimate CD Games Collection 4 / Assassins 4 (1999)(Weird Science).iso / misc / omega / source / mmelee.c < prev    next >
C/C++ Source or Header  |  1997-05-02  |  8KB  |  312 lines

  1. /* omega copyright (c) 1987,1988,1989 by Laurence Raphael Brothers */
  2. /* mmelee */
  3. /* various functions to do with monster melee */
  4.  
  5. #include "glob.h"
  6.  
  7.  
  8. void m_hit(m,dtype)
  9. struct monster *m;
  10. int dtype;
  11. {
  12.   if (m->uniqueness == COMMON) {
  13.     strcpy(Str3,"a ");
  14.     strcat(Str3,m->monstring);
  15.   }
  16.   else strcpy(Str3,m->monstring);
  17.   if ((Player.status[DISPLACED] > 0) && (random_range(2) == 1))
  18.     mprint("The attack was displaced!");
  19.   else  p_damage(random_range(m->dmg),dtype,Str3);
  20. }
  21.  
  22.  
  23.  
  24. /* execute monster attacks versus player */
  25. void tacmonster(m)
  26. struct monster *m;
  27. {
  28.   int i=0;
  29.   drawvision(Player.x,Player.y);
  30.   transcribe_monster_actions(m);
  31.   while ((i < strlen(m->meleestr)) && (m->hp > 0)) {
  32.     if (m->uniqueness == COMMON) {
  33.       strcpy(Str4,"The ");
  34.       strcat(Str4,m->monstring);
  35.     }
  36.     else strcpy(Str4,m->monstring);
  37.     if (m->meleestr[i] == 'A') {
  38.       strcat(Str4," attacks ");
  39.       strcat(Str4,actionlocstr(m->meleestr[i+1]));
  40.       if (Verbosity == VERBOSE) mprint(Str4);
  41.       monster_melee(m,m->meleestr[i+1],0);
  42.     }
  43.     else if (m->meleestr[i] == 'L') {
  44.       strcat(Str4," lunges ");
  45.       strcat(Str4,actionlocstr(m->meleestr[i+1]));
  46.       if (Verbosity == VERBOSE) mprint(Str4);
  47.       monster_melee(m,m->meleestr[i+1],m->level);
  48.     }
  49.     i+=2;
  50.   }
  51. }
  52.  
  53.  
  54.  
  55. void monster_melee(m,hitloc,bonus)
  56. struct monster *m;
  57. char hitloc;
  58. int bonus;
  59. {
  60.   if (player_on_sanctuary())
  61.     print1("The aegis of your deity protects you!");
  62.   else {
  63.     /* It's lawful to wait to be attacked */
  64.     if (m->attacked==0) Player.alignment++;
  65.     m->attacked++;
  66.     if (m->uniqueness == COMMON) {
  67.       strcpy(Str2,"The ");
  68.       strcat(Str2,m->monstring);
  69.     }
  70.     else strcpy(Str2,m->monstring);
  71.     if (monster_hit(m,hitloc,bonus))
  72.       switch(m->meleef) {
  73.       case M_NO_OP: 
  74.     strcat(Str2," touches you.");
  75.     mprint(Str2);
  76.     break;
  77.       case M_MELEE_NORMAL:
  78.     strcat(Str2," hits you.");
  79.     mprint(Str2);
  80.     m_hit(m,NORMAL_DAMAGE);
  81.     break;
  82.       case M_MELEE_NG:
  83.     strcat(Str2," hits you.");
  84.     mprint(Str2);
  85.     m_hit(m,NORMAL_DAMAGE);
  86.     if (random_range(5)==3) m_sp_ng(m);
  87.     break;
  88.       case M_MELEE_FIRE:
  89.     strcat(Str2," blasts you with fire.");
  90.     mprint(Str2);
  91.     m_hit(m,FLAME);
  92.     break;
  93.       case M_MELEE_DRAGON:
  94.     strcat(Str2," hits you and blasts you with fire.");
  95.     mprint(Str2);
  96.     m_hit(m,NORMAL_DAMAGE);
  97.     m_hit(m,FLAME);
  98.     break;
  99.       case M_MELEE_ELEC:
  100.     strcat(Str2," lashes you with electricity.");
  101.     mprint(Str2);
  102.     m_hit(m,ELECTRICITY);
  103.     break;
  104.       case M_MELEE_COLD:
  105.     strcat(Str2," freezes you with cold.");
  106.     mprint(Str2);
  107.     m_hit(m,ELECTRICITY);
  108.     break;
  109.       case M_MELEE_POISON:
  110.     strcat(Str2," hits you.");
  111.     mprint(Str2);
  112.     m_hit(m,NORMAL_DAMAGE);
  113.     if (random_range(10) < m->level) {
  114.       mprint("You've been poisoned!");
  115.       p_poison(m->dmg);
  116.     }
  117.     break;
  118.       case M_MELEE_GRAPPLE:
  119.     strcat(Str2," grabs you.");
  120.     mprint(Str2);
  121.     m_hit(m,NORMAL_DAMAGE);
  122.     Player.status[IMMOBILE]++;
  123.     break;
  124.       case M_MELEE_SPIRIT:
  125.     strcat(Str2," touches you.");
  126.     mprint(Str2);
  127.     m_hit(m,NORMAL_DAMAGE);
  128.     drain_life(m->level);
  129.     break;
  130.       case M_MELEE_DISEASE:
  131.     strcat(Str2," hits you.");
  132.     mprint(Str2);
  133.     m_hit(m,NORMAL_DAMAGE);
  134.     if (random_range(10) < m->level) {
  135.       mprint("You've been infected!");
  136.       disease(m->level);
  137.     }
  138.     break;
  139.       case M_MELEE_SLEEP:
  140.     strcat(Str2," hit you.");
  141.     mprint(Str2);
  142.     m_hit(m,NORMAL_DAMAGE);
  143.     if (random_range(10) < m->level) {
  144.       mprint("You feel drowsy");
  145.       sleep_player(m->level);
  146.     }
  147.     break;
  148.       }
  149.     else {
  150.       if (random_range(10)) strcat(Str2," missed you.");
  151.       else {
  152.     if (Verbosity == TERSE) {
  153.       switch(random_range(10)) {
  154.         case 0:
  155.           strcat(Str2," blundered severely.");
  156.           m_damage(m,m->dmg,UNSTOPPABLE); break;
  157.         case 1:
  158.           strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
  159.         case 2:
  160.           strcat(Str2," seems seriously confused.");
  161.           m->speed = min(30,m->speed*2); break;
  162.         default:
  163.           strcat(Str2," missed you.");
  164.       }
  165.     }
  166.     switch(random_range(10)) {
  167.       case 0: strcat(Str2," flailed stupidly at you."); break;
  168.       case 1: strcat(Str2," made you laugh."); break;
  169.       case 2: strcat(Str2," blundered severely.");
  170.         m_damage(m,m->dmg,UNSTOPPABLE); break;
  171.       case 3: strcat(Str2," tripped while attacking.");m_dropstuff(m);break;
  172.       case 4: strcat(Str2," seems seriously confused.");
  173.         m->speed = min(30,m->speed*2); break;
  174.       case 5: strcat(Str2," is seriously ashamed."); break;
  175.       case 6: strcat(Str2," made a boo-boo."); break;
  176.       case 7: strcat(Str2," blundered."); break;
  177.       case 8: strcat(Str2," cries out in anger and frustration."); break;
  178.       case 9: strcat(Str2," curses your ancestry."); break;
  179.     }
  180.       }
  181.       mprint(Str2);
  182.     }
  183.   }
  184. }
  185.  
  186.  
  187.  
  188. /* checks to see if player hits with hitmod vs. monster m at location hitloc */
  189. int monster_hit(m,hitloc,bonus)
  190. struct monster *m;
  191. char hitloc;
  192. int bonus;
  193. {
  194.   int i=0,blocks=FALSE,goodblocks=0,hit,riposte=FALSE;
  195.   while (i<strlen(Player.meleestr)) {
  196.     if ((Player.meleestr[i] == 'B') || (Player.meleestr[i] == 'R')) {
  197.       blocks = TRUE;
  198.       if (hitloc == Player.meleestr[i+1]) {
  199.     goodblocks++;
  200.     if (Player.meleestr[i] == 'R') riposte = TRUE;
  201.       }
  202.     }
  203.     i+=2;
  204.   }
  205.   if (! blocks) goodblocks = -1;
  206.   hit = hitp(m->hit+bonus,Player.defense+goodblocks*10);
  207.   if ((! hit) && (goodblocks > 0)) {
  208.     if (Verbosity == VERBOSE) mprint("You blocked it!");
  209.     if (riposte) {
  210.       if (Verbosity != TERSE) mprint("You got a riposte!");
  211.       if (hitp(Player.hit,m->ac)) {
  212.     mprint("You hit!");
  213.     weapon_use(0,Player.possessions[O_WEAPON_HAND],m);
  214.       }
  215.       else mprint("You missed.");
  216.     }
  217.   }
  218.   return(hit);
  219. }
  220.  
  221.  
  222.  
  223. /* decide monster actions in tactical combat mode */
  224. /* if monster is skilled, it can try see the player's attacks coming and
  225.    try to block appropriately. */
  226.  
  227. void transcribe_monster_actions(m)
  228. struct monster *m;
  229. {
  230.   int i;
  231.   char attack_loc,block_loc;
  232.   static char mmstr[80];
  233.   
  234.   int p_blocks[3];
  235.   int p_attacks[3];
  236.  
  237.   for(i=0;i<3;i++)p_blocks[i] = p_attacks[i] = 0;
  238.  
  239.   /* Find which area player blocks and attacks least in */
  240.   i = 0;
  241.   while (i<strlen(Player.meleestr)) {
  242.     if ((Player.meleestr[i] == 'B') ||
  243.     (Player.meleestr[i] == 'R')) {
  244.       if (Player.meleestr[i+1] == 'H') p_blocks[0]++;
  245.       if (Player.meleestr[i+1] == 'C') p_blocks[1]++;
  246.       if (Player.meleestr[i+1] == 'L') p_blocks[2]++;
  247.     }
  248.     else if ((Player.meleestr[i] == 'A') ||
  249.          (Player.meleestr[i] == 'L')) {
  250.       if (Player.meleestr[i+1] == 'H') p_attacks[0]++;
  251.       if (Player.meleestr[i+1] == 'C') p_attacks[1]++;
  252.       if (Player.meleestr[i+1] == 'L') p_attacks[2]++;
  253.     }
  254.     i+=2;
  255.   }
  256.  
  257.   if ((p_blocks[2] <= p_blocks[1]) &&
  258.       (p_blocks[2] <= p_blocks[0]))
  259.     attack_loc = 'L';
  260.   else if ((p_blocks[1] <= p_blocks[2]) &&
  261.        (p_blocks[1] <= p_blocks[0]))
  262.     block_loc = 'C';
  263.   else attack_loc = 'H';
  264.   if ((p_attacks[2] <= p_attacks[1]) &&
  265.       (p_attacks[2] <= p_attacks[0]))
  266.     block_loc = 'L';
  267.   else if ((p_attacks[1] <= p_attacks[2]) &&
  268.        (p_attacks[1] <= p_attacks[0]))
  269.     block_loc = 'C';
  270.   else block_loc = 'H';
  271.  
  272.   m->meleestr = mmstr;
  273.  
  274.   if (m->id != NPC)
  275.     strcpy(m->meleestr,Monsters[m->id].meleestr);
  276.   else {
  277.     strcpy(m->meleestr,"");
  278.     for(i=0;i<m->level;i+=2) 
  279.       strcat(m->meleestr,"L?R?");
  280.   }
  281.  
  282.   i = 0;
  283.   while (i<strlen(m->meleestr)) {
  284.     if ((m->meleestr[i] == 'A') || (m->meleestr[i] == 'L')) {
  285.       if (m->meleestr[i+1] == '?') {
  286.     if (m->level+random_range(30) > Player.level+random_range(20))
  287.       m->meleestr[i+1] = attack_loc;
  288.     else m->meleestr[i+1] = random_loc();
  289.       }
  290.       else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
  291.     }
  292.     else if ((m->meleestr[i] == 'B') || (m->meleestr[i] == 'R')) {
  293.       if (m->meleestr[i+1] == '?') { 
  294.     if (m->level+random_range(30) > Player.level+random_range(20))
  295.       m->meleestr[i+1] = block_loc;
  296.     else m->meleestr[i+1] = random_loc();
  297.       }
  298.       else if (m->meleestr[i+1] == 'X') m->meleestr[i+1] = random_loc();
  299.     }
  300.     i+=2;
  301.   }
  302. }
  303.  
  304. char random_loc()
  305. {
  306.   switch(random_range(3)) {
  307.   case 0:return('H');
  308.   case 1:return('C');
  309.   default:return('L');
  310.   }
  311. }
  312.